<script setup lang="ts">
import { ref, watch, nextTick, computed, onMounted, onUnmounted } from 'vue'
import { useUserStore } from '@/store/modules/user'
import { storeToRefs } from 'pinia'
import { MessageStatus, type Model } from '@/model'

const userStore = useUserStore()
const { currentMessageList, lastMessage, currentModel, modelList, windowList, showSidebar } =
  storeToRefs(userStore)
const { deleteWindow, setTestWindowList } = userStore

// 添加测试数据
onMounted(() => {
  setTestWindowList()
  initCurrentWindow()
})

// 初始化当前窗口
function initCurrentWindow() {
  if (windowList.value.length > 0 && !userStore.currentWindow) {
    userStore.currentWindow = windowList.value[0]
  }
}

defineOptions({
  name: 'MobileChat'
})

// 输入框的值
const inputValue = ref('')
const textareaRef = ref<HTMLTextAreaElement | null>(null)
const maxLines = 3 // 移动端少一行

// 模型选择相关
const showModelSelector = ref(false)
const modelSelectorRef = ref<HTMLElement | null>(null)

// 切换模型选择框显示状态
const toggleModelSelector = () => {
  showModelSelector.value = !showModelSelector.value
}

// 选择模型
const selectModel = (model: Model) => {
  userStore.currentModel = model
  showModelSelector.value = false
}

// 处理点击外部区域关闭选择框
const handleClickOutside = (event: MouseEvent) => {
  if (
    showModelSelector.value &&
    modelSelectorRef.value &&
    !modelSelectorRef.value.contains(event.target as Node)
  ) {
    showModelSelector.value = false
  }
}

// 侧边栏控制
const toggleSidebar = () => {
  showSidebar.value = !showSidebar.value
}

// 选择窗口
const handleSelectWindow = (window: any) => {
  userStore.currentWindow = window
  showSidebar.value = false // 移动端选择后自动关闭侧边栏
}

// 创建新聊天
const handleNewChat = () => {
  const newId = Date.now()
  const newWindow = {
    id: newId,
    windowName: `新聊天 ${newId}`,
    messageList: [],
    createTime: new Date().toISOString()
  }
  userStore.addWindow(newWindow)
  userStore.currentWindow = newWindow
  showSidebar.value = false // 移动端创建后自动关闭侧边栏
}

// 删除聊天
const handleDeleteChat = (id: number) => {
  deleteWindow(id)
  initCurrentWindow()
}

// 在组件挂载时添加事件监听器
onMounted(() => {
  document.addEventListener('click', handleClickOutside)
})

// 在组件卸载时移除事件监听器
onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
})

// 是否可以发送消息
const canISending = computed(() => {
  // 如果最后一条消息是打字中，则不能发送消息
  if (lastMessage.value?.status === MessageStatus.Typing) return false
  // 如果输入框为空，则不能发送消息
  if (!inputValue.value.trim()) return false
  return true
})

// 点击按钮处理
const handleButtonClick = () => {
  if (lastMessage.value?.status === MessageStatus.Typing) {
    // 如果最后一条消息是typing状态，点击后设为failed
    lastMessage.value.status = MessageStatus.Failed
  } else {
    // 否则执行正常的发送逻辑
    handleSendMessage()
  }
}

// 发送消息
const handleSendMessage = () => {
  if (!canISending.value) {
    return
  }
  // 添加用户消息
  currentMessageList.value?.push({
    id: Date.now(),
    sender: 'user',
    content: inputValue.value,
    avatar: 'C',
    status: MessageStatus.TypingDone
  })
  // 添加机器人消息
  currentMessageList.value?.push({
    id: Date.now(),
    sender: 'bot',
    content: '你好，我是小明',
    avatar: 'B',
    status: MessageStatus.Typing
  })

  // 清空输入框
  inputValue.value = ''

  // 调整 Textarea 高度
  adjustTextareaHeight()
}

// 调整 Textarea 高度
const adjustTextareaHeight = () => {
  nextTick(() => {
    const textarea = textareaRef.value
    if (textarea) {
      // Reset height to auto to get the actual scrollHeight
      textarea.style.height = 'auto'
      const scrollHeight = textarea.scrollHeight

      // Calculate line height (approximate)
      const computedStyle = window.getComputedStyle(textarea)
      const lineHeight = parseFloat(computedStyle.lineHeight) || 20 // Default line height
      const paddingTop = parseFloat(computedStyle.paddingTop) || 0
      const paddingBottom = parseFloat(computedStyle.paddingBottom) || 0

      // Calculate max height based on maxLines
      const maxHeight = lineHeight * maxLines + paddingTop + paddingBottom

      if (scrollHeight > maxHeight) {
        textarea.style.height = `${maxHeight}px`
        textarea.style.overflowY = 'auto' // Show scrollbar
      } else {
        textarea.style.height = `${scrollHeight}px`
        textarea.style.overflowY = 'hidden' // Hide scrollbar
      }
    }
  })
}

// 键盘事件处理
const handleKeyDown = (e: KeyboardEvent) => {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault()
    handleButtonClick()
  }
}

// Watch input value changes to adjust height
watch(inputValue, () => {
  adjustTextareaHeight()
})

// Initial adjustment on mount
watch(
  textareaRef,
  newRef => {
    if (newRef) {
      adjustTextareaHeight() // Adjust on mount in case there's initial value
    }
  },
  { immediate: true }
)
</script>

<template>
  <div class="flex h-screen bg-white">
    <!-- 侧边栏 -->
    <div
      class="fixed inset-0 bg-black bg-opacity-50 z-20"
      v-if="showSidebar"
      @click="toggleSidebar"
    ></div>

    <div
      class="fixed inset-y-0 left-0 w-3/4 max-w-xs bg-white z-30 transform transition-transform duration-300 ease-in-out flex flex-col"
      :class="showSidebar ? 'translate-x-0' : '-translate-x-full'"
    >
      <!-- 侧边栏头部 -->
      <div class="p-4">
        <div class="flex items-center justify-between">
          <div class="flex items-center">
            <i class="iconfont icon-chat text-lg mr-2"></i>
            <span class="font-bold text-xl">TYAI Chat</span>
          </div>
        </div>

        <div
          class="flex items-center p-2 mt-4 hover:bg-gray-100 rounded cursor-pointer border border-gray-200"
          @click="handleNewChat"
        >
          <i class="iconfont icon-ios-add mx-1"></i>
          <span>新的聊天</span>
        </div>
      </div>

      <!-- 聊天列表 -->
      <nav class="flex-1 overflow-y-auto scroll-container">
        <div class="space-y-1 flex flex-col gap-2">
          <div
            v-for="item in windowList"
            :key="item.id"
            class="group cursor-pointer rounded-md py-2 px-3 flex items-center hover:bg-gray-100"
            :class="{ 'bg-gray-100': userStore.currentWindow?.id === item.id }"
            @click="handleSelectWindow(item)"
          >
            <span>{{ item.windowName }}</span>
            <i
              class="iconfont icon-ios-close ml-auto text-gray-400 hover:text-gray-600"
              @click.stop="handleDeleteChat(Number(item.id))"
            ></i>
          </div>
        </div>
      </nav>

      <!-- 底部用户信息 -->
      <div class="border-t border-gray-200 p-3">
        <div class="flex items-center gap-2">
          <div class="w-8 h-8 bg-gray-800 rounded-full flex items-center justify-center text-white">
            C
          </div>
          <div class="flex-1 truncate">
            <div class="text-sm font-medium">用户名</div>
            <div class="text-xs text-gray-500 truncate">user@example.com</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 主内容区 -->
    <div class="flex flex-col w-full h-full">
      <!-- 顶部导航栏 -->
      <header class="flex items-center justify-between p-3 border-b border-gray-200 bg-white">
        <button class="p-2" @click="toggleSidebar">
          <i class="iconfont icon-ios-menu text-lg"></i>
        </button>
        <div class="flex items-center">
          <i class="iconfont icon-chat text-lg mr-2"></i>
          <span class="font-medium">{{ currentModel?.name || 'Chatbot App' }}</span>
        </div>
        <button class="p-2 relative" @click.stop="toggleModelSelector" ref="modelSelectorRef">
          <i class="iconfont icon-ios-arrow-down text-gray-800"></i>

          <!-- 模型选择弹出框 -->
          <div
            v-if="showModelSelector"
            class="absolute top-full right-0 mt-2 bd-1 bg-white rounded-lg shadow-lg p-2 z-10 w-[220px] border border-gray-200"
            @click.stop
          >
            <div
              v-for="model in modelList"
              :key="model.id"
              class="p-2 hover:bg-gray-100 rounded cursor-pointer text-sm flex flex-col gap-1"
              @click.stop="selectModel(model)"
            >
              <div class="flex items-center justify-between">
                <span
                  class="text-gray-800"
                  :class="{ 'text-blue-500 font-medium': model.id == currentModel.id }"
                >
                  {{ model.name }}
                </span>
                <i
                  v-if="model.id == currentModel.id"
                  class="iconfont icon-ios-checkmark text-blue-500"
                ></i>
              </div>
              <span class="text-gray-400 text-xs">{{ model.description }}</span>
            </div>
          </div>
        </button>
      </header>

      <!-- 消息区域 -->
      <div class="flex-1 overflow-y-auto p-4 bg-#f5f5f6">
        <div v-if="!currentMessageList?.length" class="text-center max-w-xs mx-auto">
          <div
            class="mx-auto w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4"
          >
            <i class="iconfont icon-bot text-2xl text-gray-600"></i>
          </div>
          <h2 class="text-lg font-medium mb-1">今天有什么需要帮忙的?</h2>
        </div>

        <!-- 消息列表 -->
        <div v-else class="space-y-4">
          <div
            v-for="message in currentMessageList"
            :key="message.id"
            class="flex"
            :class="message.sender === 'user' ? 'justify-end' : 'justify-start'"
          >
            <div
              class="p-3 rounded-lg max-w-[80%]"
              :class="
                message.sender === 'user'
                  ? 'bg-blue-500 text-white rounded-tr-none'
                  : 'bg-white text-gray-800 rounded-tl-none'
              "
            >
              <p>{{ message.content }}</p>
              <div v-if="message.status === MessageStatus.Typing" class="flex mt-1">
                <div class="animate-bounce h-1 w-1 bg-gray-400 rounded-full mx-0.5 delay-75"></div>
                <div class="animate-bounce h-1 w-1 bg-gray-400 rounded-full mx-0.5 delay-100"></div>
                <div class="animate-bounce h-1 w-1 bg-gray-400 rounded-full mx-0.5 delay-150"></div>
              </div>
              <div v-if="message.status === MessageStatus.Failed" class="text-xs text-red-500 mt-1">
                发送失败
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="p-3 border-t border-gray-200 bg-white">
        <div class="flex items-end rounded-2xl border border-gray-200 bg-#f5f5f6 p-2 shadow-sm">
          <textarea
            ref="textareaRef"
            v-model="inputValue"
            placeholder="输入一条信息... (Shift+Enter 换行)"
            class="flex-1 border-none outline-none py-1 px-2 text-sm resize-none bg-#f5f5f6"
            rows="1"
            @input="adjustTextareaHeight"
            @keydown="handleKeyDown"
          ></textarea>

          <button
            class="ml-2 p-2 rounded-full flex items-center justify-center w-8 h-8"
            :class="[
              lastMessage?.status === MessageStatus.Typing
                ? 'bg-red-500 text-white'
                : canISending
                  ? 'bg-gray-800 text-white hover:bg-gray-600'
                  : 'bg-gray-300 text-gray-500'
            ]"
            @click="handleButtonClick"
          >
            <i
              v-if="lastMessage?.status !== MessageStatus.Typing"
              class="iconfont icon-ios-send text-lg"
            ></i>
            <i v-else class="iconfont icon-ios-square text-lg"></i>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
textarea {
  line-height: 1.5;
}

/* iconfont样式覆盖，调整大小和对齐 */
.iconfont {
  font-size: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
</style>
